package com.freemalll.merchant.service.impl.coopManagement;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.freemalll.merchant.domain.dto.MerchantRateDetailDto;
import com.freemalll.merchant.domain.dto.MerchantRateDto;
import com.freemalll.merchant.domain.dto.coopManagement.AssetRateEditDto;
import com.freemalll.merchant.domain.dto.coopManagement.AssetRateDetailEditDto;
import com.freemalll.merchant.domain.entity.coopManagement.MerAssetRateManageDetail;
import com.freemalll.merchant.mapper.coopManagement.MerAssetRateManageDetailMapper;
import com.freemalll.merchant.service.coopManagement.MerAssetRateManageDetailService;
import com.freemalll.merchant.utils.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 资方费率配置明细表 服务实现类
 * </p>
 *
 * @author songshixiong
 * @since 2025-07-04
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class MerAssetRateManageDetailManagerImpl extends ServiceImpl<MerAssetRateManageDetailMapper, MerAssetRateManageDetail> implements MerAssetRateManageDetailService {


    @Override
    public void batchInsert(AssetRateEditDto dto, String rateId) {
        List<MerAssetRateManageDetail> list = this.convertToEntities(dto, rateId);
        list.forEach(item -> baseMapper.insert(item));
    }

    @Override
    public void batchUpdate(AssetRateEditDto dto) {
        List<MerAssetRateManageDetail> list = this.convertToEntities(dto, dto.getRateId());
        list.forEach(item -> {
            if (StringUtils.hasText(item.getDetailId())) {
                MerAssetRateManageDetail old = baseMapper.selectById(item.getDetailId());
                if (old == null) {
                    return;
                }
                BeanUtils.copyPropertiesIgnoreNull(item, old);
                baseMapper.updateById(item);
            } else {
                MerAssetRateManageDetail convert = Convert.convert(MerAssetRateManageDetail.class, item);
                baseMapper.insert(convert);
            }
        });
    }

    @Override
    public List<AssetRateDetailEditDto> listByMonth(List<String> rateIdList) {
        return baseMapper.listByMonth(rateIdList);
    }

    @Override
    public List<AssetRateDetailEditDto> listByYear(List<String> rateIdList) {
        return baseMapper.listByYear(rateIdList);
    }

    @Override
    public void fillInRateDetails(List<MerchantRateDto> rateDtoList) {
        List<String> rateIds = rateDtoList.stream().map(MerchantRateDto::getRateId).collect(Collectors.toList());
        List<AssetRateDetailEditDto> assetRateDetailEditDtos = baseMapper.listByMonth(rateIds);
        Map<String, List<AssetRateDetailEditDto>> map = assetRateDetailEditDtos.stream()
                .collect(Collectors.groupingBy(AssetRateDetailEditDto::getRateId));
        List<MerchantRateDto> interestAndFeeModelList = this.selectInterestAndFeeModelBySourceIds(rateDtoList.stream().map(MerchantRateDto::getSourceId).collect(Collectors.toList()));
        Map<String, List<MerchantRateDto>> interestAndFeeModelMap = interestAndFeeModelList.stream()
                .collect(Collectors.groupingBy(MerchantRateDto::getSourceId));
        for (MerchantRateDto vo : rateDtoList) {
            List<AssetRateDetailEditDto> details = map.get(vo.getRateId());
            List<MerchantRateDetailDto> merchantRateDetailDtos = new ArrayList<>();
            details.forEach(detail -> {
                MerchantRateDetailDto dto = new MerchantRateDetailDto();
                dto.setInterestRate(new BigDecimal(detail.getInterestRate()));
                dto.setTimes(detail.getTimes());
                dto.setEnableFlag(detail.getEnableFlag());
                merchantRateDetailDtos.add(dto);
            });
            if (!CollectionUtils.isEmpty(merchantRateDetailDtos)) {
                populatePhaseData(vo, merchantRateDetailDtos);
            }
            List<MerchantRateDto> interestAndFeeModelDetails = interestAndFeeModelMap.get(vo.getSourceId());
            if (!CollectionUtils.isEmpty(interestAndFeeModelDetails)) {
                List<Map<String, Object>> mapList = interestAndFeeModelDetails.stream()
                        // 单个 DTO 转 Map，参数：是否忽略空值，key 转换策略（此处用默认）
                        .map(dto -> BeanUtil.beanToMap(dto, true, true))
                        .collect(Collectors.toList());
                vo.setSupportInterestAndFeeModelList(mapList);
            }
        }
    }

    @Override
    public List<MerchantRateDto> selectInterestAndFeeModelBySourceIds(List<String> sourceList) {
        return baseMapper.selectInterestAndFeeModelBySourceIds(sourceList);
    }

    public void populatePhaseData(MerchantRateDto vo, List<MerchantRateDetailDto> details) {
        for (MerchantRateDetailDto detail : details) {
            switch (detail.getTimes()) {
                case 3:
                    vo.setPhaseThere(detail);
                    break;
                case 6:
                    vo.setPhaseSix(detail);
                    break;
                case 9:
                    vo.setPhaseNine(detail);
                    break;
                case 12:
                    vo.setPhaseTwelve(detail);
                    break;
                case 18:
                    vo.setPhaseEighteen(detail);
                    break;
                case 24:
                    vo.setPhaseTwentyFour(detail);
                    break;
                case 36:
                    vo.setPhaseThirtySix(detail);
                    break;
                default:
                    break;
            }
        }
    }

    public List<MerAssetRateManageDetail> convertToEntities(AssetRateEditDto dto, String rateId) {
        List<MerAssetRateManageDetail> entities = new ArrayList<>();
        if (dto.getPhaseThere() != null) {
            addPhase(entities, rateId, 3, dto.getPhaseThere().getInterestRate(), dto.getPhaseThere().getDetailId());
        }
        if (dto.getPhaseSix() != null) {
            addPhase(entities, rateId, 6, dto.getPhaseSix().getInterestRate(), dto.getPhaseSix().getDetailId());
        }
        if (dto.getPhaseNine() != null) {
            addPhase(entities, rateId, 9, dto.getPhaseNine().getInterestRate(), dto.getPhaseNine().getDetailId());
        }
        if (dto.getPhaseTwelve() != null) {
            addPhase(entities, rateId, 12, dto.getPhaseTwelve().getInterestRate(), dto.getPhaseTwelve().getDetailId());
        }
        if (dto.getPhaseEighteen() != null) {
            addPhase(entities, rateId, 18, dto.getPhaseEighteen().getInterestRate(), dto.getPhaseEighteen().getDetailId());
        }
        if (dto.getPhaseTwentyFour() != null) {
            addPhase(entities, rateId, 24, dto.getPhaseTwentyFour().getInterestRate(), dto.getPhaseTwentyFour().getDetailId());
        }
        if (dto.getPhaseThirtySix() != null) {
            addPhase(entities, rateId, 36, dto.getPhaseThirtySix().getInterestRate(), dto.getPhaseThirtySix().getDetailId());
        }
        return entities;
    }

    private void addPhase(List<MerAssetRateManageDetail> list,
                          String rateId,
                          int times,
                          String value, String detailId) {
        if ((value == null || value.trim().isEmpty()) && !StringUtils.hasText(detailId)) {
            return; // 空值跳过
        }

        MerAssetRateManageDetail entity = new MerAssetRateManageDetail();
        if (detailId != null) {
            entity.setDetailId(detailId);
        }
        entity.setRateId(rateId);
        entity.setTimes(times);
        if (StringUtils.hasText(value)) {
            entity.setInterestRate(new BigDecimal(value));
        } else {
            entity.setInterestRate(null);
        }
        entity.setEnableFlag(true);
        list.add(entity);
    }
}
